<?php


namespace App\Service\client;


use App\Common\RedisUtils;
use App\Common\Res;
use App\Common\SendMsgUtils;
use App\Common\StringUtils;
use App\Constants\ErrorCode;
use App\Model\form\UserDeviceTrait;
use App\Request\client\UserDeviceRequest;
use Hyperf\DbConnection\Db;
use Hyperf\Utils\ApplicationContext;
use HyperfException\Json;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class taskService
{
    use Res, RedisUtils, SendMsgUtils, UserDeviceTrait, StringUtils;

    /**
     * 设备登录
     * @param array $params
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function appLogin(int $fd, array $params): array
    {
        ApplicationContext::getContainer()->get(UserDeviceRequest::class)->validated($params['data'], __FUNCTION__);
        try {
            return Db::transaction(function () use ($fd, $params) {
                /*根据imei查询设备数据*/
                $unionId = trim($params['data']['unionId']);
                $device = $this->getUserDeviceInfo($unionId);
                if (empty($device)) {
                    $res_data['status'] = 0;
                    $res_data['msg'] = 'device LogIn error';
                    $result = $this->sendDeviceLogin($fd, $res_data);
                    return $this->Error(ErrorCode::ERROR, '设备不存在');
                }
                /*删除redis原有token，记录新token*/
                $this->hDel($this->hKey, $device->token);
                /*更新账户token*/
                $linkData = $fd . $unionId;
                $token = $this->createDeviceToken($linkData);
                $device->token = $token;
                $device->update(['token' => $device->token]);
                /*存储新的redis*/
                $device = $device->toArray();
                $device['popTime'] = time();
                $device['fd'] = $fd;
                $device['runing_status'] = '';
                $device['runing_steps'] = '';
                $this->hSet($this->hKey, $token, json_encode($device, 256));
                $res_data['token'] = $token;
                $res_data['status'] = 1;
                $res_data['msg'] = 'device appLogin success';
                $result = $this->sendDeviceLogin($fd, $res_data);
                return $this->Success('登录成功', $device);
            });
        } catch (\Throwable $ex) {
            Db::rollBack();
            $res_data['status'] = 0;
            $res_data['msg'] = $ex->getMessage();
            $result = $this->sendDeviceLogin($fd, $res_data);
            return $this->Error(ErrorCode::ERROR, '登录失败' . $ex->getMessage());
        }
    }

    /**
     *设备心跳
     * @param int $fd
     * @param array $params
     * @return array
     */
    public function appPop(int $fd, array $params): array
    {
        ApplicationContext::getContainer()->get(UserDeviceRequest::class)->validated($params, __FUNCTION__);
        try {
            $token = trim($params['token']);
            $deviceInfo = $this->hGet($this->hKey, $token);
            if (empty($deviceInfo)) {
                $res = $this->closeFdLink($fd);
                return $this->Error(ErrorCode::ERROR, 'device pop close');
            }
            $deviceArr = json_decode($deviceInfo, true);
            $deviceArr['popTime'] = time();
            $deviceArr['fd'] = $fd;
            $deviceArr['runing_status'] = $params['data']['runing_status'];
            $deviceArr['runing_steps'] = $params['data']['runing_steps'];

            if ($deviceArr['token'] != $token) {
                return $this->Error(ErrorCode::ERROR, 'device pop 设备token验证不通过');
            }

            $this->hSet($this->hKey, $token, json_encode($deviceArr, 256));
            $res_data['status'] = 1;
            $res_data['msg'] = 'device pop success';
            var_dump('------------------------------当前心跳fd-----------------------'.$fd);
            $result = $this->sendDevicePop($fd, $res_data);
            return $this->Success('心跳成功', $res_data);
        } catch (\Throwable $ex) {
            $res_data['status'] = 0;
            $res_data['msg'] = $ex->getMessage();
            $result = $this->sendDevicePop($fd, $res_data);
            return $this->Error(ErrorCode::ERROR, '心跳失败' . $ex->getMessage());
        }

    }

}